#pragma once
#include <iostream>
#include<string>
#include<cstring>
#include<set>
#include<stdio.h>

using namespace std;
class Command
{
public:
    Command()
    {
        //白名单
        _safe_command.insert("ls");
        _safe_command.insert("touch"); // touch filename
        _safe_command.insert("pwd");
        _safe_command.insert("whoami");
        _safe_command.insert("which"); // which pwd
    }
    bool SafeCommand(const string &cmdstr)
    {
        for(auto &cmd:_safe_command)
        {
            if(strncmp(cmdstr.c_str(),cmd.c_str(),cmd.size())==0)
            {
                return true;
            }
        }
        return false;
    }
    string Excute(const string &cmdstr)
    {
        if(!SafeCommand(cmdstr))
        {
            return "unsafe";
        }
        string ruselt;
        FILE* fp = popen(cmdstr.c_str(),"r");
        if(fp)
        {
            char line[1024];
            while(fgets(line,sizeof(line),fp))
            {
                ruselt += line;
            }
        }
        return ruselt.empty() ? "success" : ruselt;
    }
    void HandlerCommand(int sockfd, InetAddr addr)
    {
        // 长服务,只要不关闭一直运行
        while (true)
        {
            char commandbuffer[1024];
            size_t n = recv(sockfd, commandbuffer, sizeof(commandbuffer) - 1, 0); // 收到消息,recv等价于read
            if (n > 0)
            {
                commandbuffer[n] = 0;
                LOG(INFO, "get message from client %s, message: %s\n", addr.AddrStr().c_str(), commandbuffer);

                string result = Excute(commandbuffer);
                send(sockfd, result.c_str(), result.size(), 0); // 发送消息,send等价于write
            }
            else if (n == 0)
            {
                LOG(INFO, "client %s quit\n", addr.AddrStr().c_str());
                break;
            }
            else
            {
                LOG(ERROR, "read error: %s\n", addr.AddrStr().c_str());
                break;
            }
        }
    }
    ~Command()
    {

    }

private:
    set<string> _safe_command;
};